﻿#region using statements

using System;
using System.IO;
using System.Text;

#endregion

namespace NGen.Managers.Logging
{
	public class Logger : ILogger
	{
		#region local fields

		/// <summary>
		/// 	name of the file to which this logger is writing text
		/// </summary>
		protected String m_filename;

		/// <summary>
		/// 	stringbuilder helper object
		/// </summary>
		protected StringBuilder m_stringBuilder = new StringBuilder();

		/// <summary>
		/// 	stream writer used to write the file
		/// </summary>
		protected StreamWriter m_writer;

		#endregion

		#region constructors

		/// <summary>
		/// 	construct a new logger object
		/// </summary>
		/// <param name = "p_logfile">filepath to use</param>
		/// <param name = "p_initialLoggingLevel">default logger logging level</param>
		protected internal Logger(string p_logfile, LoggingLevel p_initialLoggingLevel) {
			m_filename = p_logfile;
			CurrentLogLevel = p_initialLoggingLevel;
			PrefixTimestamp = true;
			AlsoWriteToMainLog = true;
			if(!Directory.Exists("logs")) {
				Directory.CreateDirectory("logs");
			}
		}

		#endregion

		#region ILogger implementation

		/// <summary>
		/// 	the logging level of this logger, any messages specified above this logging
		/// 	level will not be logged
		/// </summary>
		public LoggingLevel CurrentLogLevel { get; set; }

		/// <summary>
		/// 	text which is writtin before each log message
		/// </summary>
		public String PrefixText { get; set; }

		/// <summary>
		/// 	text which is written after each log message
		/// </summary>
		public String PostfixText { get; set; }

		/// <summary>
		/// 	should the timestamp be prefixed to log messages
		/// </summary>
		public bool PrefixTimestamp { get; set; }

		/// <summary>
		/// 	should messages be logged to both the main log and the individual logger
		/// </summary>
		public bool AlsoWriteToMainLog { get; set; }

		/// <summary>
		/// 	close the logfile
		/// </summary>
		public void Close() {
			if(m_writer != null) {
				m_writer.Close();
			}
			m_writer = null;
		}

		/// <summary>
		/// 	clears the logfile
		/// </summary>
		public void ClearLog() {
			if(m_writer != null) {
				m_writer.Close();
			}

			if(File.Exists(m_filename)) {
				File.Delete(m_filename);
			}
		}

		/// <summary>
		/// 	convenience method for building a string
		/// </summary>
		/// <param name = "p_string"></param>
		/// <returns></returns>
		public StringBuilder BuildString(string p_string) {
			m_stringBuilder.Clear();
			return m_stringBuilder.Append(p_string);
		}

		/// <summary>
		/// 	writes a string to the log file
		/// </summary>
		/// <param name = "p_message">string to write</param>
		/// <param name = "p_level">the logging level to use</param>
		public void Write(string p_message, LoggingLevel p_level = LoggingLevel.MINIMAL) {
			if(CurrentLogLevel == LoggingLevel.NONE ||
			   CurrentLogLevel < p_level) {
				return;
			}

			//construct the message
			var tempString = new StringBuilder();
			if(PrefixTimestamp) {
				tempString.Append("[").Append(DateTime.Now.ToLongTimeString()).Append("]-");
			}
			tempString.Append(PrefixText).Append(p_message).Append(PostfixText);

			//create the write stream if it doesn't exist
			if(m_writer == null) {
				m_writer = File.CreateText(m_filename);
				Write("Log Created");
			}

			m_writer.WriteLine(tempString.ToString());
		}

		#endregion
	}
}